/*
 * @Author: Swance
 * @Date: 2023-12-30
 * @Description: 橡皮擦插件
 */

import { fabric } from 'fabric';
import '@/libs/eraser_brush.mixin.js';
import { IEditor } from '@/types/global';
import { BoardSyncEvent, JsonOption } from '@/utils/Const.ts';

class EraserPlugin {
  canvas: fabric.Canvas;
  editor: IEditor;
  eraserMode: boolean;
  static pluginName = 'EraserPlugin';
  static apis: string[] = ['setEraserMode', 'erase'];

  constructor(canvas: fabric.Canvas, editor: IEditor) {
    this.canvas = canvas;
    this.editor = editor;
    this.eraserMode = false;
    this.init();
  }

  init() {
    const { canvas } = this;
    let oldPathElements: Map<String, any> = new Map();
    canvas.on('erasing:start', (e) => {
      oldPathElements.clear();
      const pathList = canvas.getObjects('path');
      pathList.forEach((item) => {
        oldPathElements.set(item.id, item.toJSON(JsonOption));
      });
    });
    canvas.on('erasing:end', ({ targets }) => {
      // targets 为受影响的所有元素，因为橡皮擦可能一次擦了几个元素
      if (!targets.length) return;
      const oldElementJson: any[] = [];
      const newElementJson: any[] = [];
      targets.forEach((item: any) => {
        if (oldPathElements.has(item.id)) {
          oldElementJson.push(oldPathElements.get(item.id));
        }
        newElementJson.push(item.toJSON(JsonOption));
      });
      this.editor.emit(BoardSyncEvent.UPDATE, {
        isNewAction: true,
        oldElements: [...oldElementJson],
        newElements: [...newElementJson],
      });
    });
  }

  setEraserMode(params: boolean) {
    this.canvas.isDrawingMode = params;
  }

  erase() {
    this.setEraserMode(true);
    const { canvas } = this;
    canvas.freeDrawingBrush = new fabric.EraserBrush(canvas);
    canvas.freeDrawingBrush.width = 25;
  }
}
export default EraserPlugin;
